﻿using System;
using System.Data;

namespace Marmat.Forms.Views
{
    namespace DataGrid
    {
        public class Row
        {
            public Forms.DataGrid DataGrid { get; private set; }

            internal Row(Forms.DataGrid dataGrid, DataRow Row)
            {
                this.DataGrid = dataGrid;
                this._dataRow = Row;
            }

            public DataRow BaseRow => this._dataRow;

            private DataRow _dataRow { get; set; }

            /// <summary>
            /// 返回或设置 当前Row指定列的单元格的值
            /// </summary>
            /// <param name="Column"></param>
            public object this[Column Column]
            {
                get => this[Column.Name];
                set => this[Column.Name] = value;
            }

            /// <summary>
            /// 获取一个值，该值指示指定的列是否包含 null 值。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            /// <remarks></remarks>
            public bool IsNull(string columnName)
            {
                return this.BaseRow.IsNull(columnName) || this.BaseRow[columnName] is null;
            }

            /// <summary>
            /// 获取一个值，该值指示指定的列是否包含 null 值。
            /// </summary>
            /// <param name="column">列</param>
            /// <returns></returns>
            /// <remarks></remarks>
            public bool IsNull(Column column)
            {
                return this.BaseRow.IsNull(column.Name) || this.BaseRow[column.Name] is null;
            }

            /// <summary>
            /// 获取一个值，该值指示指定的 System.Data.DataColumn 和 System.Data.DataRowVersion 是否包含 null 值。
            /// </summary>
            /// <param name="column">列</param>
            /// <param name="version">System.Data.DataRowVersion 值之一，用于指定行版本。 可能值为 Default、Original、Current 和 Proposed。</param>
            /// <returns></returns>
            public bool IsNull(Column column, DataRowVersion version)
            {
                return this.BaseRow.IsNull(column.DataColumn, version) || this.BaseRow[column.Name, version] is null;
            }

            /// <summary>
            /// 返回或设置 当前Row指定列的单元格的值
            /// </summary>
            /// <param name="Index"></param>
            public object this[int Index]
            {
                get
                {
                    string columnName = this.DataGrid.Columns[Index].Name;
                    return this[columnName];
                }

                set
                {
                    string ColName = this.DataGrid.Columns[Index].Name;
                    this[ColName] = value;
                }
            }

            /// <summary>
            /// 获取指定列中存储的数据的指定版本。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <param name="version">System.Data.DataRowVersion 值之一，用于指定需要的行版本。 可能值为 Default、Original、Current 和 Proposed。</param>
            public object this[string columnName, DataRowVersion version]
            {
                get
                {
                    var value = this.BaseRow[columnName, version];
                    if (ReferenceEquals(value, DBNull.Value))
                    {
                        value = null;
                    }

                    return value;
                }
            }

            /// <summary>
            /// 返回或设置 当前Row指定列的单元格的值
            /// </summary>
            /// <param name="columnName"></param>
            public object this[string columnName]
            {
                get
                {
                    var value = this.BaseRow[columnName];
                    if (ReferenceEquals(value, DBNull.Value))
                    {
                        value = null;
                    }

                    return value;
                }

                set
                {
                    if (value is null)
                    {
                        value = DBNull.Value;
                    }

                    this.BaseRow[columnName] = value;
                }
            }

            /// <summary>
            /// 返回当前对象指定列的单元格的值，并转换为 string 类型。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            public string ItemAsString(string columnName)
            {
                return (string)this[columnName];
            }

            /// <summary>
            /// 返回当前对象指定列的单元格的值，并转换为 double 类型。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            public double ItemAsDouble(string columnName)
            {
                return (double)this[columnName];
            }

            /// <summary>
            /// 返回当前对象指定列的单元格的值，并转换为 int 类型。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            public int ItemAsInt32(string columnName)
            {
                return (int)this[columnName];
            }

            /// <summary>
            /// 返回当前对象指定列的单元格的值，并转换为 DateTime 类型。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            public DateTime ItemAsDateTime(string columnName)
            {
                return (DateTime)this[columnName];
            }

            /// <summary>
            /// 返回当前对象指定列的单元格的值，并转换为 bool 类型。
            /// </summary>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            public bool ItemAsBoolean(string columnName)
            {
                if (this.IsNull(columnName))
                    return false;
                return (bool)this[columnName];
            }

            /// <summary>
            /// 返回当前对象指定列的单元格的值，并转换为指定的类型。
            /// </summary>
            /// <typeparam name="TValue">返回的类型</typeparam>
            /// <param name="columnName">列的名称</param>
            /// <returns></returns>
            public TValue ItemAs<TValue>(string columnName)
            {
                var value = this[columnName];
                if (value is null)
                    value = default;
                return (TValue)value;
            }

            /// <summary>
            /// 删除行。
            /// </summary>
            /// <returns></returns>
            /// <remarks></remarks>
            public bool Delete()
            {
                return this.DataGrid.Rows.Delete(this);
            }

            /// <summary>
            /// 获取 Row 在Table中的位置
            /// </summary>
            /// <value></value>
            /// <returns></returns>
            /// <remarks></remarks>
            public int Index
            {
                get
                {
                    var rows = this.DataGrid.Rows;
                    for (int i = 0, loopTo = rows.Count - 1; i <= loopTo; i++)
                    {
                        if (ReferenceEquals(rows[i].BaseRow, this.BaseRow))
                        {
                            return i;
                        }
                    }

                    return -1;
                }
            }

            /// <summary>
            /// 提交自上次调用 System.Data.DataRow.AcceptChanges 以来对该行进行的所有更改。
            /// </summary>
            /// <remarks></remarks>
            public void AcceptChanges()
            {
                this.BaseRow.AcceptChanges();
            }

            /// <summary>
            /// 获取与该行和 System.Data.DataRowCollection 的关系相关的当前状态。
            /// </summary>
            /// <returns></returns>
            public DataRowState RowState
            {
                get
                {
                    return this.BaseRow.RowState;
                }
            }


            /// <summary>
            /// 移除行。
            /// </summary>
            /// <remarks></remarks>
            public void Remove()
            {
                this.DataGrid.Rows.Remove(this);
            }
        }
    }
}